package com.gitee.feizns.quickstart.dict.spring.boot.autoconfigure.redis;

import com.gitee.feizns.quickstart.dict.AbstractDictDepositor;
import com.gitee.feizns.quickstart.dict.DictDepositor;
import com.gitee.feizns.quickstart.dict.Entry;
import com.gitee.feizns.quickstart.dict.Permission;
import com.gitee.feizns.quickstart.jackson.JsonUtils;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Redis dict depositor
 * @author feizns
 * @since 2025/1/6
 */
public class RedisDictDepositor<T extends Entry> extends AbstractDictDepositor<T> {

    /**
     * 快速入门 dict redis 条目
     */
    public static final String QUICKSTART_DICT_REDIS_ENTRIES = "QUICKSTART_DICT_REDIS_ENTRIES";

    /**
     * 字符串 Redis 模板
     */
    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 入门类
     */
    private final Class<T> entryClass;

    /**
     * Redis dict depositor
     * @param delegate 委托
     */
    public RedisDictDepositor(Class<T> entryClass, DictDepositor<T> delegate, StringRedisTemplate stringRedisTemplate) {
        super(delegate);
        this.entryClass = entryClass;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public DictDepositor<T> reload() {
        if ( delegate != null ) {
            delegate.reload();
            delegate.list().forEach(e -> stringRedisTemplate.opsForHash().put(QUICKSTART_DICT_REDIS_ENTRIES, e.getKey(), JsonUtils.toJson(e)));
        }
        return this;
    }

    @Override
    public List<T> list() {
        Collection<Object> values = stringRedisTemplate.opsForHash().entries(QUICKSTART_DICT_REDIS_ENTRIES).values();
        return values.stream().map(value -> JsonUtils.parse(value.toString(), entryClass)).collect(Collectors.toList());
    }

    @Override
    public T get(String key) {
        Object entry = stringRedisTemplate.opsForHash().get(QUICKSTART_DICT_REDIS_ENTRIES, key);;
        //找不见下发查找
        if ( entry == null ) {
            //代理查找
            entry = delegate.get(key);
            //找见了存储到当前缓存
            if ( entry != null )
                stringRedisTemplate.opsForHash().put(QUICKSTART_DICT_REDIS_ENTRIES, key, JsonUtils.toJson(entry));
        }
        return entry != null ? JsonUtils.parse(entry.toString(), entryClass) : null;
    }

    @Override
    public void put(T entry) {
        T dict = get(entry.getKey());
        if ( dict != null && dict.getPermission() == Permission.ReadOnly )
            throw new UnsupportedOperationException(String.format("不支持修改只读字典[%s]", dict.getKey()));
        stringRedisTemplate.opsForHash().put(QUICKSTART_DICT_REDIS_ENTRIES, entry.getKey(), JsonUtils.toJson(entry));
        //代理存储
        delegate.put(entry);
    }

    @Override
    public boolean exists(String key) {
        return stringRedisTemplate.opsForHash().hasKey(QUICKSTART_DICT_REDIS_ENTRIES, key);
    }

    @Override
    public T delete(String key) {
        T entry = get(key);
        if ( entry != null ) {
            if ( entry.getPermission() == Permission.ReadOnly )
                throw new UnsupportedOperationException(String.format("不支持删除只读字典[%s]", entry.getKey()));
            stringRedisTemplate.opsForHash().delete(QUICKSTART_DICT_REDIS_ENTRIES, key);
            delegate.delete(key);
        }
        return entry;
    }

}
